/**
 * Copyright (C) 2009, 2010 SC 4ViewSoft SRL
 *  
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *  
 *      http://www.apache.org/licenses/LICENSE-2.0
 *  
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package cc.mango.android.chart;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import java.text.DecimalFormat;

import org.achartengine.chart.AbstractChart;
import org.achartengine.chart.ScatterChart;
import org.achartengine.model.XYMultipleSeriesDataset;
import org.achartengine.model.XYSeries;
import org.achartengine.renderer.DefaultRenderer;
import org.achartengine.renderer.SimpleSeriesRenderer;
import org.achartengine.renderer.XYMultipleSeriesRenderer;
import org.achartengine.renderer.XYMultipleSeriesRenderer.Orientation;
import org.achartengine.util.MathHelper;

import cc.mango.common.FinalKey;
import cc.telecomdigital.tdstock.StringUtils;
import cc.telecomdigital.tdstock.Framework.UniqueItem.TDStockLog;
import cc.telecomdigital.tdstock.activity.chart.NvChart;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.graphics.Paint.Align;
import android.graphics.Paint.FontMetrics;
import android.graphics.Paint.Style;
import android.view.MotionEvent;
import static cc.mango.android.chartutil.ChartCommons.*;

/**
 * The XY chart rendering class.
 */
public abstract class UpXYChart extends BaseXYChart
{

	protected Bitmap	bm;
	protected int		bmWidth;

	//X坐标起始位置的索引
	List<Integer>		xLabelIndexs;

	protected Bitmap	circle;

	//图片需要调整的距离
	protected float	bmMargin	= 2;

	/**
	 * Builds a new XY chart instance.
	 * 
	 * @param dataset the multiple series dataset
	 * @param renderer the multiple series renderer
	 */
	public UpXYChart(XYMultipleSeriesDataset dataset,
			XYMultipleSeriesRenderer renderer)
	{
		super(dataset, renderer);
	}

	public UpXYChart(XYMultipleSeriesDataset dataset,
			XYMultipleSeriesRenderer renderer, NvChart nvChart)
	{
		// TODO Auto-generated constructor stub
		super(dataset, renderer, nvChart);
	}

	/**
	 * The graphical representation of a series.
	 * 
	 * @param canvas the canvas to paint to
	 * @param paint the paint to be used for drawing
	 * @param points the array of points to be used for drawing the series
	 * @param seriesRenderer the series renderer
	 * @param yAxisValue the minimum value of the y axis
	 * @param seriesIndex the index of the series currently being drawn
	 */
	public abstract void drawSeries(Canvas canvas, Paint paint,
			float[] points, SimpleSeriesRenderer seriesRenderer,
			float yAxisValue, int seriesIndex);

	/**
	 * Returns if the chart should display the points as a certain shape.
	 * 
	 * @param renderer the series renderer
	 */
	public boolean isRenderPoints(SimpleSeriesRenderer renderer)
	{
		return false;
	}

	public void drawTopBm(Canvas canvas, float x, float y, int width,
			int height, String text)
	{

		Bitmap bitmap = getBitmap(width, height);

		canvas.drawBitmap(bitmap, x, y, null);

		// Paint paint = new Paint();  //haibo, 2011-06-13,  设置字体抗锯齿效果
		Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG
				| Paint.FAKE_BOLD_TEXT_FLAG);
		paint.setColor(UP_CHART_BACKGROUND_COLOR);
		paint.setTextAlign(Align.CENTER);

		paint.setTextSize(UP_CHART_BITMAP_TEXTSIZE);
		paint.setTypeface(Typeface.DEFAULT_BOLD);
		//	  paint.setStrokeWidth(5);

		canvas.drawText(text, x + 1.0f * width / 2, y + height * 3.0f / 4,
				paint);

		TDStockLog.d("Print_Info", "text:" + text);

	}

	public void drawCircle(Canvas canvas, float x, float y)
	{
		TDStockLog.d("Print_Info", "circle : y:" + y);
		/* Paint paint = new Paint();
		 paint.setColor(INDICATOR_CIRCLE_COLOR);
		 paint.setStyle(Style.FILL);	  
		 paint.setAntiAlias(true);
		 float radius = 8;
		 canvas.drawCircle(x, y, radius, paint);  */

		Bitmap bm = getCircleBitmap();
		Paint paint = new Paint();
		paint.setAntiAlias(true);
		canvas.drawBitmap(bm, x - bm.getWidth() / 2, y - bm.getHeight() / 2,
				paint);
	}

	public void drawBackgroundDottedLine(Canvas canvas, int x, int y,
			int width, int height, Paint paint)
	{

		paint.setColor(Color.WHITE);
		paint.setAlpha(128);
		paint.setStyle(Style.FILL);
		paint.setStrokeWidth(2);

		int lineCount = 4;//vertical number
		float spaceHeight = 1.0f * height / (lineCount - 1);//verticla space height
		int shortLineCount = 50;//horizontal number short line
		float lineAndSpaceLength = 1.0f * width / shortLineCount;
		float spaceLength = 1.0f * width / 100;
		float shortLineLength = lineAndSpaceLength - spaceLength;

		float startY = y;
		float startX = x;
		float stopX;
		for (int i = 0; i < lineCount; i++)
		{
			startY = y + i * spaceHeight;
			for (int j = 0; j < shortLineCount; j++)
			{
				startX = x + j * lineAndSpaceLength;
				stopX = startX + shortLineLength;
				canvas.drawLine(startX, startY, stopX, startY, paint);
			}

		}

	}

	public float getBmX(float x)
	{
		float bmX = x - 1.0f * bmWidth / 2;

		float left = screenR.left - bmMargin;

		float right = screenR.right - bmWidth + bmMargin;

		if (bmX < left)
		{

			bmX = left;

		}
		else if (bmX > right)
		{

			bmX = right;
		}

		return bmX;

	}

	public float getXLocation(int index)
	{
		float xLocation = (float) (index * xPixelsPerUnit + screenR.left);
		return xLocation;
	}

	public float getYLocation(int index)
	{
		XYSeries series = mDataset.getSeriesAt(0);
		float yLocation = (float) (screenR.bottom - yPixelsPerUnit
				* (series.getY(index) - this.calcRange[2]));
		return yLocation;
	}

	//	  
	public String getYValue(int index)
	{
		XYSeries series = mDataset.getSeriesAt(0);

		//		  return StringUtils.formatToFiveCharsRuleWithoutSign(series.getY(index)+"");

		return getStringPrice(series.getY(index));//保留6位小数
	}

	public void initSize(int width, int height)
	{

		leftWidth = width / 10;
		rightWidth = width / 25;
		topHeight = height / 8;
		bottomHeight = height / 8;
		bmWidth = width / 8;
	}

	public List<String> getYLabels(final double start, final double end,
			int numLabels)
	{

		if (yLabels != null && yLabels.size() != 0)
		{

			return yLabels;
		}

		List<String> labels = new ArrayList<String>();

		if (numLabels < 1)
		{
			numLabels = 1;
		}

		if (Math.abs(start - end) < 0.0000001f)
		{
			//		    	labels.add(StringUtils.formatToFiveCharsRuleWithoutSign(0+""));
			labels.add(StringUtils
					.formatToFiveCharsRuleWithoutSign(end + ""));

			return labels;
		}

		double s = start;
		double e = end;

		if (s > e)
		{

			double tmp = s;
			s = e;
			e = tmp;
		}
		double xStep = Math.abs(s - e) / (numLabels - 1);
		// Compute x starting point so it is a multiple of xStep.

		for (int i = 0; i <= numLabels - 1; i++)
		{
			double z = start + i * xStep;
			//		      labels.add(z);
			labels.add(StringUtils.formatToFiveCharsRuleWithoutSign(z + ""));
		}

		yLabels = labels;

		return labels;
	}

	public void setXLabels(List<String> xLabels)
	{

		this.xLabels = xLabels;
	}

	public List<String> getXLabels()
	{

		return xLabels;
	}

	public List<Float> getXLabelLocations(float x1, float x2, int numLabels)
	{

		if (xLabelLocations != null)
		{
			return xLabelLocations;
		}

		if (x1 > x2)
		{

			float temp = x1;
			x1 = x2;
			x2 = temp;
		}

		xLabelLocations = new ArrayList<Float>();

		//先处理是一个星期的情况
		List<Integer> xLabelIndexs = getXLabelIndexs();
		if (xLabelIndexs != null)
		{ //如果xLabelIndexs不为空，说明是1week，返回一个星期的坐标位置

			for (Integer i : xLabelIndexs)
			{

				xLabelLocations.add(this.getXLocation(i));
			}

			return xLabelLocations;

		}

		if (numLabels < 2)
		{

			xLabelLocations.add(x1);

			return xLabelLocations;
		}

		if (getIsOneDayChart() && numLabels == 2)
		{

			xLabelLocations.add(x1);

			xLabelLocations.add(x1 + (x2 - x1) * 0.6f);

			return xLabelLocations;
		}

		float step = (x2 - x1) / (numLabels - 1);

		for (int i = 0; i < numLabels; i++)
		{

			xLabelLocations.add(x1 + i * step);
		}

		return xLabelLocations;
	}

	public List<Integer> getXLabelIndexs()
	{

		return xLabelIndexs;

	}

	public void setXLabelIndexs(List<Integer> list)
	{

		xLabelIndexs = list;

	}

	public boolean getIsWeekChart()
	{

		if (xLabelIndexs == null)
		{

			return false;
		}
		else
		{
			return true;
		}

	}

	public void drawWeekChartVerticalLine(Canvas canvas, int top, int bottom,
			Paint paint)
	{

		paint.setColor(Color.WHITE);
		paint.setAlpha(150);
		paint.setStyle(Style.FILL);
		paint.setStrokeWidth(3);

		if (xLabelLocations == null)
		{
			return;
		}

		int size = xLabelLocations.size();
		for (int i = 1; i < size; i++)
		{

			float x = xLabelLocations.get(i);
			canvas.drawLine(x, bottom, x, top, paint);

		}

	}

	private Bitmap getBitmap(int width, int height)
	{

		if (bm == null)
		{

			bm = Bitmap.createScaledBitmap(nvChart.getBm(), width, height,
					false);
		}

		return bm;
	}

	protected void drawXLabels(Canvas canvas, Paint paint)
	{

		if (mRenderer.isShowXlabels())
		{
			FontMetrics fm = paint.getFontMetrics();
			bottomMargin = (fm.bottom - fm.top) * 1.3f;
			xLabels = this.getXLabels();
			xLabelLocations = this.getXLabelLocations(screenR.left,
					screenR.right, xLabels.size());

			int length = xLabels.size();

			TDStockLog.d("Print_Info", "xLabels.size():" + xLabels.size());

			for (int i = 0; i < length; i++)
			{
				String label = xLabels.get(i);
				float location = xLabelLocations.get(i);

				paint.setColor(mRenderer.getLabelsColor());
				paint.setTextAlign(Align.CENTER);
				canvas.drawText(label, location, screenR.bottom
						+ bottomMargin, paint);//xlabel    

			}

		}
	}

	protected void drawTopBackground(DefaultRenderer renderer, Canvas canvas,
			int left, int top, int right, int bottom, Paint paint)
	{
		if (renderer.isApplyBackgroundColor())
		{
			paint.setColor(UP_CHART_TOP_REGINE_COLOR);
			paint.setStyle(Style.FILL);
			canvas.drawRect(left - 1, top, right + 1, bottom, paint);
		}
	}

	public Bitmap getCircleBitmap()
	{

		if (circle == null)
		{

			circle = nvChart.getCircleBm();
		}

		return circle;
	}

	public boolean getIsOneDayChart()
	{

		return FinalKey.INTRADAY_DATETYPE_TODAY.equals(nvChart.getDateType());

	}

	protected double getMinY(double minY, double minimumY)
	{

		if (!isEqual(minY, 0) && !isEqual(minimumY, 0))
		{

			minY = Math.min(minY, (float) minimumY);

			calcRange[2] = minY;
		}
		else if (!isEqual(minY, 0))
		{

			calcRange[2] = minY;
		}
		else if (!isEqual(minimumY, 0))
		{

			calcRange[2] = minimumY;
			minY = minimumY;
		}

		return minY;
	}

}
